﻿namespace CacheBehaviorExtension
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ServiceModel.Description;
    using CacheProvider;
    using CacheProviderEntities;

    public class CachingOperationBehavior : Attribute, IOperationBehavior
    {
        [Description("Unique Key for Cache.")]
        public string Key { get; set; }

        [Description("The time that the response object will remain in Cache. If not set, behavior depends on configured provider.")]
        public TimeSpan Timeout { get; set; }

        [Description(@"Name of the Region under which the Key\Value will remain in Cache.  Region must pre-exist and should be supported by the configured provider. If not supported, this value has no impact")]
        public string RegionName { get; set; }

        [Description("Tags to annotage objects. It should be supported by the configured provider. If not supported, this value has no impact")]
        public List<string> CacheTags { get; set; }

        //[Description("Dependencies that if change will invalidate the related Cache entry")]
        //public DependencyInfo DependencyDetails { get; set; }

        public CacheDependencyTypes DependencyType { get; set; }

        public string DependencyDbConnectionString { get; set; }

        public string DependencySqlQuery { get; set; }

        public string DependencyDbName { get; set; }


        #region IOperationBehavior Members

        public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.ClientOperation clientOperation)
        {
        }

        public void ApplyDispatchBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
        {
            DependencyInfo dependencyDetails = null;

            if (DependencyType == CacheDependencyTypes.SQLDependency
                && !string.IsNullOrEmpty(this.DependencySqlQuery)
                && !string.IsNullOrEmpty(this.DependencyDbConnectionString)
                && !string.IsNullOrEmpty(this.DependencyDbName))
            {
                dependencyDetails = new DependencyInfo(DependencyType)
                {
                    DBConnectionString = this.DependencyDbConnectionString,
                    IsSQLSelectQueryBased = true,
                    DBName = this.DependencyDbName,
                };

                dependencyDetails.SelectQueries.Add(this.DependencySqlQuery);
            }

            dispatchOperation.Invoker = new CachingOperationInvoker(dispatchOperation.Invoker, Key, RegionName, Timeout, CacheTags, dependencyDetails);
        }

        public void Validate(OperationDescription operationDescription)
        {
        }

        #endregion
    }
}
